package proj.unions.resource;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import proj.unions.general.L;
import proj.unions.general.OnMyCallBack;
import proj.unions.general.SuperTools;
import proj.unions.general.Text;
import android.accounts.NetworkErrorException;
import android.app.Activity;

public class DownloadAPK implements Runnable, RMConstDefine {
	
	private static final int DOWNLOAD_STATUS_SUCCESSFUL = 1;
	private static final int DOWNLOAD_STATUS_NONE = 0;
	private static final int DOWNLOAD_STATUS_FAILURE_IO = -1;
	private static final int DOWNLOAD_STATUS_FAILURE_NET = -2;
	
	private static String FileName = null;
	
	private Activity mActivity = null;
	private OnMyCallBack mOnMyCallBack = null;
	private int mCurClientVersion = -1;
	private int mNewNewestVersion = -1;
	private boolean mNeedUpdate = false;
	private String mAPKUrl = null;
	
	private long mFileCurLength = -1;
	private long lastSpeed = 0;//速度
	private long trunkSize = 0;//块大小
	private boolean isChange = false;
	private boolean isEndTimer = false;
	
	private int mCode = -1;

	public DownloadAPK(Activity a, OnMyCallBack l, JSONObject json)
	{
		mActivity = a;
		mOnMyCallBack = l;
		
		try {
			mCurClientVersion = Integer.valueOf(SuperTools.getInstance().getVersionCode());
			mNewNewestVersion = json.getInt(KEY_NEWEST_VERSION);//新的版本号
			mNeedUpdate = json.getBoolean(KEY_IS_UPDATE);//是否需要更新
			
			mAPKUrl = json.getString(KEY_APK_URL);
//			mAPKUrl = "http://cdn.hh108.com/fish/apk/fish3.apk";//临时写死

			L.d("==========apkUrl:" + mAPKUrl);
			lastSpeed = 0;
			trunkSize = 0;
			isChange = false;
			isEndTimer = false;
			FileName = SuperTools.getInstance().getInstallAPKPath() + mNewNewestVersion + ".apk";
			
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		if (mActivity == null || mOnMyCallBack == null)
		{
			mOnMyCallBack.onReceive("error", 0, null);
			return;
		}
		
		//对比版本
	//	if (mCurClientVersion < mNewNewestVersion)
//		{
			//判断文件是否已经存在
			int flag = 0;
			mFileCurLength = isExistFile(FileName);
			if(mFileCurLength > 0)
			{
				// 启动定时器
				startTimer();
				flag = DownloadForBreakpointContinuingly();
			}
			else
			{
				// 启动定时器
				startTimer();
				flag = downloadFile();
			}
			if( flag == DOWNLOAD_STATUS_SUCCESSFUL )
			{
//				SuperTools.getInstance().writeLocalFile("curNewestVersion", String.valueOf(mNewNewestVersion));
//				SuperTools.getInstance().writeLocalFile("curClientVersion", String.valueOf(mNewClientVersion));
				JSONObject json = new JSONObject();
				try {
					json.put(KEY_APK_PATH, FileName);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				mOnMyCallBack.onReceive("yes", 1, json);
			}
			else if(flag == DOWNLOAD_STATUS_NONE)
			{
				SuperTools.getInstance().showErrorDialog(Text.getKey("Net")/*"网络"*/, 
						Text.getKey("Net_CallManager_ErrorNetD")/*"网络下载异常，请联系管理员*/ + " Error:" + mCode);
			}
			else if(flag == DOWNLOAD_STATUS_FAILURE_IO)
			{
				SuperTools.getInstance().showErrorDialog(Text.getKey("Net")/*"网络"*/, 
						Text.getKey("Net_CallManager_ErrorNetRW")/*"网络读写异常，请联系管理员*/ + " Error:" + mCode);
			}
			else if(flag == DOWNLOAD_STATUS_FAILURE_NET)
			{
				SuperTools.getInstance().showErrorDialog(Text.getKey("Net")/*"网络"*/, 
						Text.getKey("Net_CallManager_ErrorNet")/*"网络连接异常，请联系管理员*/ + " Error:" + mCode);
			}
//		}
//		else
//			mOnMyCallBack.onReceive("no", -1, null);//无需安装，直接跳过
		
			isEndTimer = true;
	}
	
	//下载
	private int downloadFile()
	{
		float retainLength = ResManager.mIamgeTotalength * (1 - ResManager.mCountPercent);
		float countPercent = ResManager.mCountPercent;
		
		try {
			byte[] buffer = new byte[2048];
			HttpGet getMethod = new HttpGet(mAPKUrl);
			HttpClient httpClient = new DefaultHttpClient();
			HttpResponse response = httpClient.execute(getMethod);
			
			long fileSize = response.getEntity().getContentLength();
			
			int byteReaded = 0;
			int curSize = 0;
			
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) 
			{
				InputStream is = response.getEntity().getContent();
				File f = new File(FileName);
				if (f.exists())
					f.delete();
				if (!f.getParentFile().exists()) {
					f.getParentFile().mkdirs();
				}
				f.createNewFile();
				FileOutputStream fos = new FileOutputStream(f);
				do {
					try {
						byteReaded = is.read(buffer);
						curSize += byteReaded;
						trunkSize += byteReaded;
						float curProcess = ((float) curSize / (float) fileSize * 100);
						int count = (int) (curProcess / 2);
						if (isChange) {
							isChange = false;
							lastSpeed = trunkSize / 1024;
							trunkSize = 0;
						}
						
//						String content = "当前更新APK版本:" + mNewNewestVersion + 
//								" 已下载  " + (curSize / 1024 ) + "KB / " + 
//								(fileSize / 1024) + "KB  " +
//										lastSpeed + "KB/s";
						
						float ret = ((float)curSize / (float)fileSize) * retainLength;
						ResManager.mCountPercent = countPercent + (ret / ResManager.mIamgeTotalength);
						String content = Text.getKey("Net_DownloadApk")/*"正在下载新版本*/+ ":" + mNewNewestVersion + ".apk";				
						mOnMyCallBack.onReceive(content, 2, null);
						
					} catch (IOException e) {
						try {
							throw new NetworkErrorException(e);
						} catch (NetworkErrorException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
							L.d("download:" + e1.getMessage());
							return DOWNLOAD_STATUS_FAILURE_NET;
						}
					}
					if (byteReaded > 0) {
						fos.write(buffer, 0, byteReaded);
					}
					fos.flush();
				} while (byteReaded != -1);
				fos.close();
				
				return DOWNLOAD_STATUS_SUCCESSFUL;
			}
			else
				mCode = code;
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			L.d("download:" + e.getMessage());
			return DOWNLOAD_STATUS_FAILURE_NET;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			L.d("download:" + e.getMessage());
			return DOWNLOAD_STATUS_FAILURE_IO;
		}

		return DOWNLOAD_STATUS_NONE;
	}

	//断点续传
	private int DownloadForBreakpointContinuingly()
	{
		long fileFullSize = 0;
		int code = -1;
		try {
			HttpGet getMethod = new HttpGet(mAPKUrl);
			HttpClient httpClient = new DefaultHttpClient();
			HttpResponse response = httpClient.execute(getMethod);
			fileFullSize = response.getEntity().getContentLength();//总长度
		
			code = response.getStatusLine().getStatusCode();

		} catch (ClientProtocolException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		L.d("======code:" + code);
		mCode = code;
		L.d("=====mFileCurLength:" + mFileCurLength + "   fileFullSize:" + fileFullSize);
		if (mFileCurLength == fileFullSize)
		{
			//如果长度已经相等,就是本地已经下载完
			return DOWNLOAD_STATUS_SUCCESSFUL;
		}
		
		long nPos = mFileCurLength;
		
		InputStream input = null;
		long fileSize = 0;//计算用
		try {
			URL obbUrl = new URL(mAPKUrl);
			L.d("======mAPKUrl:" + mAPKUrl);
			try {
				HttpURLConnection httpConnection = (HttpURLConnection)obbUrl.openConnection();
				//设置 User-Agent
				httpConnection.setRequestProperty("User-Agent", "NetFox");
				//设置断电续传的开始
				httpConnection.setRequestProperty("Range", "bytes=" + nPos + "-" + fileFullSize);
				//获得输入流
				input = httpConnection.getInputStream();
				
				fileSize = nPos;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				L.d("download2:" + e.getMessage());
				return DOWNLOAD_STATUS_FAILURE_IO;
			}
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			L.d("download2:" + e.getMessage());
			return DOWNLOAD_STATUS_NONE;
		}
		
		try {
			RandomAccessFile oSavedFile = new RandomAccessFile(FileName, "rw");
			// 定位文件指针到 nPos位置
			oSavedFile.seek(nPos);

			byte[] b = new byte[2048];
			int byteReaded = 0;
			int curSize = (int)nPos;
			while ((byteReaded = input.read(b, 0, 2048)) > 0) 
			{
				curSize += byteReaded;
				trunkSize += byteReaded;
				float curProcess = ((float) curSize / (float) fileSize * 100);
				int count = (int) (curProcess / 2);
				if (isChange) {
					isChange = false;
					lastSpeed = trunkSize / 1024;
					trunkSize = 0;
				}
				
				String content = "当前更新APK版本:" + mNewNewestVersion + 
						" 已下载  " + (curSize / 1024 / 1024) + "MB / " + 
						(fileFullSize / 1024 / 1024) + "MB  " +
								lastSpeed + "KB/s";
				mOnMyCallBack.onReceive(content, 2, null);
				oSavedFile.write(b, 0, byteReaded);
			}
			oSavedFile.close();
			input.close();
			return DOWNLOAD_STATUS_SUCCESSFUL;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			L.d("download2:" + e.getMessage());
			return DOWNLOAD_STATUS_FAILURE_IO;
		}
	}
	
	private void startTimer()
	{
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					while(!isEndTimer)
					{
						isChange =  true;
						Thread.sleep(500);
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();
	}
	
	//检测Apk文件是否已经下载
	public long isExistFile(String fileName)
	{
		File f = new File(fileName);
		if ( !f.exists() )
			return -1;
		long length = f.length();
	    return length;
	}	
	
}
